import uuid,dill,json
from abc import ABC

from handlers import BaseHandler
from model import User,Group
from tornado.gen import coroutine
from forms import CreateUserForm,LoginForm
from utils.multithreading import executor
from tornado.stack_context import wrap


class LoginHandler(BaseHandler,ABC):

    @coroutine
    def post(self):
        body = json.loads(self.request.body)
        form = LoginForm(**body)
        if form.validate():
            query = self.session.query(User).filter_by(username = body.get("username"))
            user = yield executor(wrap(query.first))
            if user is None:
                self.finish({"status":False,"response":"找不到用户"})
                return
            if user.check_password_is_correct(body.get("password")):
                uuid_hex = uuid.uuid4().hex
                self.redis.set(uuid_hex,dill.dumps(user.to_dict()))
                self.redis.expire(uuid_hex,60 * 30)
                self.finish({"status":True,"response":uuid_hex})
            else:
                self.finish({"status":False,"response":"密码不正确"})
        else:
            self.finish({"status":False,"response":form.errors})

    def delete(self):
        get_auth = self.request.headers.get("Authorization")
        self.redis.delete(get_auth)
        self.finish({"status":True,"response":get_auth})


class UserHandler(BaseHandler,ABC):
    @coroutine
    def get(self):
        query = self.session.query(User)
        users = yield executor(query.all)
        response = []
        for user in users:
            response.append(user.to_dict())
        self.finish({"status":True,"response":response})

    @coroutine
    def post(self):
        form = CreateUserForm(**json.loads(self.request.body))
        if form.validate():
            data = form.data
            user = User(**data)
            query = self.session.query(User).filter_by(username = user.username)
            first_user = yield executor(query.first)
            if first_user is None:
                user.set_password(data.get('password'))
                self.session.add(user)
                yield executor(wrap(self.session.commit))
                self.finish({"status":True,'response':user.to_dict()})
            else:
                user.update_value(**data)
                user.set_password(data.get('password'))
                yield executor(wrap(self.session.commit))
                self.finish({"status":True,'response':user.to_dict()})
        else:
            self.finish({"status":False,'response':form.errors})

    @coroutine
    def delete(self):
        user_id = int(self.request.body)
        query = self.session.query(User).filter_by(id = user_id)
        user = yield executor(query.first)
        self.session.delete(user)
        yield executor(wrap(self.session.commit),*())
        self.finish({"status":True,'response':user.to_dict()})
